package org.bizming.passport.dao;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.bizming.base.service.SqlHelper;
import org.bizming.passport.model.Passport;
import org.bizming.record.model.RecordType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

public class PassportMysqlDao implements PassportDao {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private JdbcTemplate jdbcTemplate;

	private SqlHelper sqlHelper;

	private String tableName = "passport";

	public boolean add(Passport passport) {
		List<Object> values = new ArrayList<Object>();
		String sql = sqlHelper.sqlAdd(passport, values, getTableName());
		logger.info(sql);

		Object[] o = values.toArray();
		int affectRow = jdbcTemplate.update(sql, o);

		sqlHelper.clear(values);
		sqlHelper.clear(o);

		if (affectRow > 0) {
			return true;
		} else {
			return false;
		}
	}

	public Passport getByUsername(String username) {

		String sql = buildViewSql("username");
		logger.info(sql);
		Passport passport = jdbcTemplate.queryForObject(sql,
				new PassportMapper(), username);

		return passport;
	}

	public Passport getByEmail(String email) {

		String sql = buildViewSql("email");
		logger.info(sql);
		Passport passport = jdbcTemplate.queryForObject(sql,
				new PassportMapper(), email);

		return passport;
	}

	public boolean updatePwd(String username, String pwd) {
		String sql = buildUpdateSql("password");
		logger.info(sql);

		int affectRow = jdbcTemplate.update(sql, pwd, username);
		if (affectRow > 0) {
			return true;
		} else {
			return false;
		}
	}

	public boolean updateEmail(String username, String email) {
		String sql = buildUpdateSql("email");
		logger.info(sql);

		int affectRow = jdbcTemplate.update(sql, email, username);
		if (affectRow > 0) {
			return true;
		} else {
			return false;
		}
	}

	public boolean removeByUsername(String username) {
		String sql = buildRemoveSql();
		logger.info(sql);
		int affectRow = jdbcTemplate.update(sql, username);
		if (affectRow > 0) {
			return true;
		} else {
			return false;
		}
	}

	public List<Passport> selectList(int limit, int page) {

		String sql = sqlHelper.sqlSelectList(RecordType.class, getTableName());
		logger.info(sql);

		Object[] args = new Object[] { limit, page };

		List<Passport> rows = jdbcTemplate.query(sql, new PassportMapper(),
				args);

		sqlHelper.clear(args);

		return rows;
	}

	/** 构建删除sql */
	private String buildRemoveSql() {
		StringBuilder builder = new StringBuilder(100);
		builder.append("delete from ").append(getTableName())
				.append(" where username=? ");
		return builder.toString();
	}

	/** 构建修改sql */
	private String buildUpdateSql(String field) {
		StringBuilder builder = new StringBuilder(100);
		builder.append("update ").append(getTableName());
		builder.append(" set ").append(field).append("=?");
		builder.append("where username=?");
		return builder.toString();

	}

	/** 构建获取sql */
	private String buildViewSql(String field) {
		Map<String, Field> map = buildMap(getClass());

		StringBuilder column = new StringBuilder(100);
		for (Map.Entry<String, Field> entry : map.entrySet()) {
			column.append(entry.getKey()).append(",");
		}

		StringBuilder builder = new StringBuilder(100);
		builder.append("select ").append("id,")
				.append(column.substring(0, column.length() - 1))
				.append(" from ").append(getTableName());
		builder.append("where ").append(field).append("=?");

		return builder.toString();
	}

	/** 将对象转成map */
	private <T> Map<String, Field> buildMap(Class<T> cls) {
		Map<String, Field> map = new HashMap<String, Field>();
		Field[] fields = cls.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			map.put(field.getName(), field);
		}
		return map;
	}

	class PassportMapper implements RowMapper<Passport> {

		public Passport mapRow(ResultSet rs, int rowNum) throws SQLException {
			Passport passport = new Passport();
			passport.setId(rs.getInt("id"));
			passport.setUsername(rs.getString("username"));
			passport.setPassword(rs.getString("password"));
			passport.setEmail(rs.getString("email"));
			passport.setIsChecked(rs.getInt("isChecked"));
			passport.setActionTime(rs.getLong("actionTime"));
			passport.setCreateTime(rs.getLong("createTime"));
			return passport;
		}

	}

	// ===================================
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

}
